﻿#include "CycleArray.h"
#include <algorithm>
#include <numeric>
#include <iostream>
#include <chrono>
#include <string>
#include <deque>
#include <list>

using namespace std;
using namespace Transfer;

int main(int argc, char* argv[])
{	
	auto arr = CycleArray<long>(10);
	for (auto i = 0; i < 5; ++i)
	{
		arr.push(i);
	}
	assert(arr.size() == 5);

	vector<long> vv;
	for (auto i = 0; i < 30; ++i)
	{
		arr.push(i);
		vv.push_back(i);
		if (vv.size() > 10)
		{
			vv.erase(vv.begin());
		}
	}
	assert(arr.size() == 10);

	auto sum = accumulate(arr.begin(), arr.end(), 0);
	assert(sum == 245);
	auto v = arr.to_vector();
	sum = accumulate(v.begin(), v.end(), 0);
	assert(sum == 245);
	sum = accumulate(vv.begin(), vv.end(), 0);
	assert(sum == 245);

	auto arr1 = arr;
	for (auto i = 0; i < 30; ++i)
	{
		arr1.push(i);
	}
	sum = accumulate(arr1.begin(), arr1.end(), 0);
	assert(sum == 245);

	auto arr2(std::move(arr));
	for (auto i = 0; i < 30; ++i)
	{
		arr2.push(i);
	}
	sum = accumulate(arr2.begin(), arr2.end(), 0);
	assert(sum == 245);

	arr = arr2;
	sum = accumulate(arr.begin(), arr.end(), 0);
	assert(sum == 245);

	for (auto i = 0; i<10; ++i)
	{
		arr.push(i);
	}

	decltype(arr)::iterator iter = arr.begin();
	assert(*iter == 0);
	*iter = 13;
	assert(arr[0] == 13);
	++iter;
	assert(*iter == 1);
	auto it = iter++;
	assert(*it == 1 && *iter == 2);

	for (auto i = 0; i<100000; ++i)
	{
		arr.push(10- i);
		sum = accumulate(arr.begin(), arr.end(), 0);
	}

	size_t count = 3000;
	auto begin = chrono::system_clock::now();
	CycleArray<string> strArr(count);
	for(auto i=0; i<1000000; ++i)
	{
		strArr.push("hello world");
	}
	auto duration = chrono::system_clock::now() - begin;
	cout << "a:" << chrono::duration_cast<chrono::microseconds>(duration).count() << "ms" << endl;

	begin = chrono::system_clock::now();
	vector<string> strV;
	/*
	for(auto i=0; i<1000000; ++i)
	{
		strV.push_back("hello world");
		if (strV.size() >= count)
		{
			strV.erase(strV.begin());
		}
	}
	duration = chrono::system_clock::now() - begin;
	cout << "v:" << chrono::duration_cast<chrono::microseconds>(duration).count() << "ms" << endl;
	*/

	begin = chrono::system_clock::now();
	deque<string> strQ;
	for(auto i=0; i<1000000; ++i)
	{
		strQ.push_back("hello world");
		if (strQ.size() >= count)
		{
			strQ.pop_front();
		}
	}
	duration = chrono::system_clock::now() - begin;
	cout << "q:" << chrono::duration_cast<chrono::microseconds>(duration).count() << "ms" << endl;

	begin = chrono::system_clock::now();
	list<string> strL;
	for(auto i=0; i<1000000; ++i)
	{
		strL.push_back("hello world");
		if (strL.size() >= count)
		{
			strL.pop_front();
		}
	}
	duration = chrono::system_clock::now() - begin;
	cout << "l:" << chrono::duration_cast<chrono::microseconds>(duration).count() << "ms" << endl;

	begin = chrono::system_clock::now();
	for(auto i=0; i<10000; ++i)
	{
		for(auto it = strArr.begin(); it != strArr.end(); ++it)
		{
			auto val = *it;
		}
	}
	duration = chrono::system_clock::now() - begin;
	cout << "a access:" << chrono::duration_cast<chrono::microseconds>(duration).count() << "ms" << endl;

	begin = chrono::system_clock::now();
	for(auto i=0; i<10000; ++i)
	{
		for(auto it = strV.begin(); it != strV.end(); ++it)
		{
			auto val = *it;
		}
	}
	duration = chrono::system_clock::now() - begin;
	cout << "v access:" << chrono::duration_cast<chrono::microseconds>(duration).count() << "ms" << endl;

	begin = chrono::system_clock::now();
	for(auto i=0; i<10000; ++i)
	{
		for(auto it = strQ.begin(); it != strQ.end(); ++it)
		{
			auto val = *it;
		}
	}
	duration = chrono::system_clock::now() - begin;
	cout << "q access:" << chrono::duration_cast<chrono::microseconds>(duration).count() << "ms" << endl;


	return 0;
}